/*
 * Copyright (c) 2025 GuoKaiHong (Shenzhen) Technology Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */


#ifndef QR_ENCODE_H
#define QR_ENCODE_H

#ifndef BYTE
typedef unsigned char BYTE;
typedef unsigned char *LPBYTE;
typedef unsigned short WORD;
#define L_SRELEN STRLEN
#endif


#ifndef min
template<typename T>
inline T min(const T& a, const T& b)
{
    return (a < b) ? a : b;
}
#endif


#ifndef BOOL
typedef int BOOL;
#endif


#ifndef LPCSTR
#define LPCSTR const char *
#endif


#define MAX_ALLCODEWORD 3706
#define MAX_DATACODEWORD 2956
#define MAX_CODEBLOCK 153
#define MAX_MODULESIZE 177

typedef struct TagRsBlockInfo {
    int ncRSBlock;
    int ncAllCodeWord;
    int ncDataCodeWord;
} RS_BLOCKINFO, *LPRS_BLOCKINFO;

typedef struct TagQrVersioninfo {
    int nVersionNo;
    int ncAllCodeWord;
    int ncDataCodeWord[4];
    int ncAlignPoint;
    int nAlignPoint[6];
    RS_BLOCKINFO rsBlickInfo1[4];
    RS_BLOCKINFO rsBlockInfo2[4];
} QR_VERSIONINFO, *LPQR_VERSIONINFO;

class CQR_Encode {
public:
    // 默认构造函数
    CQR_Encode(){};
    // 析构函数
    ~CQR_Encode();

public:
    // 定义纠错等级
    int m_nLevel;
    // 定义QR码版本
    int m_nVersion;
    // 是否自动扩展QR码尺寸
    BOOL m_bAutoExtent;
    // 掩码编号
    int m_nMaskingNo;

public:
    // 符号尺寸
    int m_nSymbleSize;
    // 模块数据
    BYTE m_byModuleData[MAX_MODULESIZE][MAX_MODULESIZE];

private:
    // 数据码字位数
    int m_ncDataCodeWordBit;
    // 数据码字
    BYTE m_byDataCodeWord[MAX_DATACODEWORD];

    // 数据块数量
    int m_ncDataBlock;
    // 数据块模式
    BYTE m_byBlockMode[MAX_DATACODEWORD];
    // 数据块长度
    int m_nBlockLength[MAX_DATACODEWORD];

    // 总码字数
    int m_ncAllCodeWord;
    // 总码字
    BYTE m_byAllCodeWord[MAX_ALLCODEWORD];
    // RS工作区
    BYTE m_byRSWork[MAX_CODEBLOCK];

public:
    // 编码数据
    BOOL EncodeData(int nLevel, int nVersion, BOOL bAutoExtent, int nMaskingNo, LPCSTR lpsSource0, int ncSource = 0);

    // GBK转UTF-8编码
    int Gbk2Utf8(char *utfStr, const char *srcStr, int maxUtfSRELEN);
    // 判断是否是中文字符
    int IsCN(const char *strSrc);

private:
    // 获取编码版本
    int GetEncodeVersion(int nVersion, LPCSTR lpsSource, int ncLength);
    // 编码源数据
    BOOL EncodeSourceData(LPCSTR lpsSource, int ncLength, int nVerGroup);

    // 获取位长度
    int GetBitLength(BYTE nMode, int ncData, int nVerGroup);

    // 设置位流
    int SetBitStream(int nIndex, WORD wData, int ncData);

    // 判断是否是数字类型数据
    BOOL IsNumeralData(unsigned char c);
    // 判断是否是字母类型数据
    BOOL IsAlphabetData(unsigned char c);
    // 判断是否是汉字类型数据
    BOOL IsKanjiData(unsigned char c1, unsigned char c2);
    // 字母转二进制
    BYTE AlphabetToBinaly(unsigned char c);
    // 汉字转二进制
    WORD KanjiToBinaly(WORD wc);

    // 获取RS码字
    void GetRSCodeWord(LPBYTE lpbyRSWork, int ncDataCodeWord, int ncRSCodeWord);

private:
    // 格式化模块
    void FormatModule();
    // 设置功能模块
    void SetFunctionModule();
    // 设置定位图案
    void SetFinderPattern(int x, int y);
    // 设置对齐图案
    void SetAlignmentPattern(int x, int y);
    // 设置版本图案
    void SetVersionPattern();
    // 设置码字图案
    void SetCodeWordPattern();
    // 设置掩码图案
    void SetMaskingPattern(int nPatternNo);
    // 设置格式信息图案
    void SetFormatInfoPattern(int nPatternNo);
    // 计算罚分
    int CountPenalty();
};


#endif // end of _QR_ENCODE_H
